THIS IS THE TCP-IP CODE THAT I HAVE WRITTEN FOR THE DOS MODE IN "C" LANGUAGE:
COPYRIGHT: GAIRIK BHATTACHARYA
THE FIRST PART:
/*
# receives numbered UDP datagrams from a remote host.
#
# Usage:
# udp-recv source_adr [-p<port_number>][-t<timeout>]
#
# <port_number> defaults to 9870.
# Use source_adr of 255.255.255.255 to accept packets from anyone.
#
# Renaud Waldura # on Sep 18 16:51:24 1995
# converted from Perl to trumpet abi by Dan Kegel and Chris Thomas 6/7/1996
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <conio.h>
#include <ctype.h>
#include <tcpabi/tcpabi.h>
#include <tcpabi/tdprint.h>
#define TRUE (1)
#define FALSE (0)
#define BUFLEN 512
static char inbuf[BUFLEN];
int port = 9870;
int timeout_interval = 20; // anything less than 18 seems to be treated as 0
void print_usage( char *progname )
{
printf(" Usage: %s <ip_adr> [-p <port_number>][-t <timeout_interval>]\n", progname);
}
void get_stat(unsigned h)
{
int i;
unsigned size = 65535;
tcpabi_session_info_t __fAr *info;
i = tcpabi_udp_status(h, 0, &size, &info);
if (_tcpabi_errno != 0)
printf("bad status! errno %d\n", _tcpabi_errno);
else
printf("status: errno %d, return %d, size %d, ip_src %lx %d.%d.%d.%d port_loc %d, ip_dst %lx %d.%d.%d.%d port_rem %d, active %d\n",
_tcpabi_errno, i, size,
info->ip_src,
((unsigned char *)&info->ip_src)[0],
((unsigned char *)&info->ip_src)[1],
((unsigned char *)&info->ip_src)[2],
((unsigned char *)&info->ip_src)[3],
info->port_loc,
info->ip_dst,
((unsigned char *)&info->ip_dst)[0],
((unsigned char *)&info->ip_dst)[1],
((unsigned char *)&info->ip_dst)[2],
((unsigned char *)&info->ip_dst)[3],
info->port_rem,
info->active);
}
int receive_test(char *hostname)
{
unsigned int receive_handle;
unsigned long dst_ip;
unsigned dst_port;
unsigned src_port;
int n;
int err;
printf("resolving address for host %s\n", hostname);
if (isdigit(hostname[0])) {
dst_ip = htonl(aton(hostname));
} else if ((dst_ip = resolve(hostname)) == 0L) {
printf("receive_test: Can't resolve '%s' to IP address\n", hostname);
return FALSE;
}
// open a handle to receive packets on specified port
dst_port = 0;
src_port = port;
receive_handle = tcpabi_udp_open(dst_ip, dst_port, src_port, UDP_OPEN_NORMAL, NULL);
if (receive_handle == NULL_HANDLE) {
printf("error opening receive_handle!\n");
return FALSE;
}
printf("ip %d.%d.%d.%d, dst_port %d, src_port %d, handle %d, timeout %d\n",
((unsigned char *)&dst_ip)[0],
((unsigned char *)&dst_ip)[1],
((unsigned char *)&dst_ip)[2],
((unsigned char *)&dst_ip)[3],
dst_port, src_port, receive_handle, timeout_interval);
#if 0
// test behavior of info call. Does it apply to the head or the tail of
// the queue?
while (!kbhit()) {
get_stat(receive_handle);
sleep(1);
}
getch();
#endif
for (n = 1; !kbhit(); n++) {
int i;
i = tcpabi_udp_recv(receive_handle, inbuf, BUFLEN, timeout_interval, UDP_SEND_NORMAL, NULL, NULL);
if (i == -1) {
} else {
printf("test_udprecv: got %d bytes: '", i);
fwrite(inbuf, sizeof(char), i, stdout);
printf("'\n");
get_stat(receive_handle);
}
}
tcpabi_udp_close(receive_handle, UDP_CLOSE_NORMAL);
return TRUE;
}
#ifdef __386__
#include <dos.h>
#define DPMI_INT 0x31
/*-------------------------------------------------------------------------
Get a block of DOS memory.
Return flat pointer to it, or NULL on failure.
Also place segmented real mode pointer in *seg, *off, and protected mode
selector in *sel. (The selector is only needed to free the memory,
thanks to the flat memory model of DOS4G.)
-------------------------------------------------------------------------*/
void *my_dos_malloc(size_t len, short *seg, short *off, short *sel)
{
union REGS regs;
// Note: The DPMI service expects the number of paragraphs not bytes.
regs.w.ax = (short) 0x0100;
regs.w.bx = (len + 0xf) >> 4;
int386(DPMI_INT, ®s, ®s);
if (regs.w.cflag) {
// Abort! Out of DOS memory!
return NULL;
}
// Result is in AX:DX (seg:sel)
*seg = regs.w.ax;
*off = 0;
*sel = regs.w.dx;
DPRINT(("allocated selector %x\n", regs.w.dx));
return (void *) (regs.w.ax << 4);
}
/*-------------------------------------------------------------------------
Free a block of DOS memory allocated with my_dos_alloc.
-------------------------------------------------------------------------*/
void my_dos_free(short sel)
{
union REGS regs;
// Note: The DPMI service expects the number of paragraphs not bytes.
regs.w.ax = (short) 0x0101;
regs.w.dx = sel;
int386(DPMI_INT, ®s, ®s);
if (regs.w.cflag) {
DPRINT(("my_dos_free: Can't free DOS memory at selector %x, error %d!\n",
sel, regs.w.ax));
}
}
#endif
void main( int argc, char *argv[] )
{
int i;
short selector;
puts("udprecv test (for UDP ABI) -- Copyright (C) 1994, Michael S. Durkin");
if((argc == 1) || (argv[1][0] == '-')) {
print_usage( argv[0] );
exit(1);
}
for (i = 2; i<argc; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'p': port = atoi(argv[i]+2); break;
case 't': timeout_interval = atoi(argv[i]+2); break;
default: print_usage(argv[0]); exit(1);
}
}
}
#ifdef __386__
scratch_flat = my_dos_malloc(BUFLEN, &scratch_seg, &scratch_off, &selector);
if (!scratch_flat) {
printf("couldn't allocate DOS memory!\n");
exit(3);
}
#endif
if( !tcpabi_installed() ) {
printf("\n UDP ABI not found\n");
exit(2);
}
receive_test(argv[1]);
exit(0);
}
THE SECOND PART OF THE TCP-IP CODE:
/*
# receives numbered UDP datagrams from a remote host.
#
# Usage:
# udp-recv source_adr [-p][-t]
#
# defaults to 9870.
# Use source_adr of 255.255.255.255 to accept packets from anyone.
#
# Renaud Waldura # on Sep 18 16:51:24 1995
# converted from Perl to trumpet abi by Dan Kegel and Chris Thomas 6/7/1996
*/
#include
#include
#include
#include
#include
#include
#include
#include
#define TRUE (1)
#define FALSE (0)
#define BUFLEN 512
static char inbuf[BUFLEN];
int port = 9870;
int timeout_interval = 20; // anything less than 18 seems to be treated as 0
void print_usage( char *progname )
{
printf(" Usage: %s [-p ][-t ]\n", progname);
}
void get_stat(unsigned h)
{
int i;
unsigned size = 65535;
tcpabi_session_info_t __fAr *info;
i = tcpabi_udp_status(h, 0, &size, &info);
if (_tcpabi_errno != 0)
printf("bad status! errno %d\n", _tcpabi_errno);
else
printf("status: errno %d, return %d, size %d, ip_src %lx %d.%d.%d.%d port_loc %d, ip_dst %lx %d.%d.%d.%d port_rem %d, active %d\n",
_tcpabi_errno, i, size,
info->ip_src,
((unsigned char *)&info->ip_src)[0],
((unsigned char *)&info->ip_src)[1],
((unsigned char *)&info->ip_src)[2],
((unsigned char *)&info->ip_src)[3],
info->port_loc,
info->ip_dst,
((unsigned char *)&info->ip_dst)[0],
((unsigned char *)&info->ip_dst)[1],
((unsigned char *)&info->ip_dst)[2],
((unsigned char *)&info->ip_dst)[3],
info->port_rem,
info->active);
}
int receive_test(char *hostname)
{
unsigned int receive_handle;
unsigned long dst_ip;
unsigned dst_port;
unsigned src_port;
int n;
int err;
printf("resolving address for host %s\n", hostname);
if (isdigit(hostname[0])) {
dst_ip = htonl(aton(hostname));
} else if ((dst_ip = resolve(hostname)) == 0L) {
printf("receive_test: Can't resolve '%s' to IP address\n", hostname);
return FALSE;
}
// open a handle to receive packets on specified port
dst_port = 0;
src_port = port;
receive_handle = tcpabi_udp_open(dst_ip, dst_port, src_port, UDP_OPEN_NORMAL, NULL);
if (receive_handle == NULL_HANDLE) {
printf("error opening receive_handle!\n");
return FALSE;
}
printf("ip %d.%d.%d.%d, dst_port %d, src_port %d, handle %d, timeout %d\n",
((unsigned char *)&dst_ip)[0],
((unsigned char *)&dst_ip)[1],
((unsigned char *)&dst_ip)[2],
((unsigned char *)&dst_ip)[3],
dst_port, src_port, receive_handle, timeout_interval);
#if 0
// test behavior of info call. Does it apply to the head or the tail of
// the queue?
while (!kbhit()) {
get_stat(receive_handle);
sleep(1);
}
getch();
#endif
for (n = 1; !kbhit(); n++) {
int i;
i = tcpabi_udp_recv(receive_handle, inbuf, BUFLEN, timeout_interval, UDP_SEND_NORMAL, NULL, NULL);
if (i == -1) {
} else {
printf("test_udprecv: got %d bytes: '", i);
fwrite(inbuf, sizeof(char), i, stdout);
printf("'\n");
get_stat(receive_handle);
}
}
tcpabi_udp_close(receive_handle, UDP_CLOSE_NORMAL);
return TRUE;
}
#ifdef __386__
#include
#define DPMI_INT 0x31
/*-------------------------------------------------------------------------
Get a block of DOS memory.
Return flat pointer to it, or NULL on failure.
Also place segmented real mode pointer in *seg, *off, and protected mode
selector in *sel. (The selector is only needed to free the memory,
thanks to the flat memory model of DOS4G.)
-------------------------------------------------------------------------*/
void *my_dos_malloc(size_t len, short *seg, short *off, short *sel)
{
union REGS regs;
// Note: The DPMI service expects the number of paragraphs not bytes.
regs.w.ax = (short) 0x0100;
regs.w.bx = (len + 0xf) >> 4;
int386(DPMI_INT, ®s, ®s);
if (regs.w.cflag) {
// Abort! Out of DOS memory!
return NULL;
}
// Result is in AX:DX (seg:sel)
*seg = regs.w.ax;
*off = 0;
*sel = regs.w.dx;
DPRINT(("allocated selector %x\n", regs.w.dx));
return (void *) (regs.w.ax << 4);
}
/*-------------------------------------------------------------------------
Free a block of DOS memory allocated with my_dos_alloc.
-------------------------------------------------------------------------*/
void my_dos_free(short sel)
{
union REGS regs;
// Note: The DPMI service expects the number of paragraphs not bytes.
regs.w.ax = (short) 0x0101;
regs.w.dx = sel;
int386(DPMI_INT, ®s, ®s);
if (regs.w.cflag) {
DPRINT(("my_dos_free: Can't free DOS memory at selector %x, error %d!\n",
sel, regs.w.ax));
}
}
#endif
void main( int argc, char *argv[] )
{
int i;
short selector;
puts("udprecv test (for UDP ABI) -- Copyright (C) 1994, Michael S. Durkin");
if((argc == 1) || (argv[1][0] == '-')) {
print_usage( argv[0] );
exit(1);
}
for (i = 2; i